package org.dangoldberg.app.http;

//Dan Goldberg

import java.lang.reflect.Constructor;
import java.net.*;
import java.nio.CharBuffer;
import java.text.*;
import java.util.*;
import java.io.*;

import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

import org.jma.lib.soap.HttpRequest;
import org.jma.lib.soap.HttpResponse;
import org.jma.lib.soap.SOAPApplication;
import org.jma.lib.soap.exceptions.HttpException;
import org.jma.lib.soap.utils.ClassLoaderUtil;
import org.jma.lib.utils.http.FileUploader;



public class SSHttpServerSSL extends Thread

{
	private String[] headerArray;
	private String[] env;
	private Socket _s=null;
	private SSLSocket ssl_s=null;
	private InputStream dataFromClient;
	private OutputStream dataToClient;
	String methodType = "";
	String http = "";
	String domain = "";
	String cgivars = "";
	String protocol = "";
	String httpVerSt = "";
	String httpVer = "0.0";
	double httpVersion = 0.0;
	String filetype = "";
	String filepath = "";
	String serverRoot = "";
	boolean send404 = false;
	String temp = "";
	String host = "";
	String ques = "";
	String filenm = "";
	String filename = "";
	String url = "";
	String headers = "";
	String ctype = "";
	int quesE = 0;
	int numEnvVars = 0;
	boolean cnt = true;
	boolean validMethod = false;
	boolean sent = false;
	boolean body = false;
	boolean isAnApplication =false;
	private HttpRequest httpRequest;
	private boolean _debug=false;
	private boolean serverType;
	private HttpResponse httpResponse;
	
	//Static definitions are shared by all the threads
	private static Hashtable _mt = new Hashtable();
	private static Properties _serverConfig;
	private static int httpPort=80;
	private static int sslPort=999;
	private static boolean sslInitiated=false;
	private static boolean httpInitiated=false;
	private static final boolean SSL_PORT_TYPE=true;
	private static final boolean HTTP_PORT_TYPE=false;
	static private HashMap soapApplications=new HashMap();
	static final byte[] EOL = 
    {(byte)'\r', (byte)'\n' };
	static final int MAX_HEADER_SIZE=65536; 

	
	public SSHttpServerSSL(int port,boolean type){
		if (type==SSL_PORT_TYPE){
			sslPort=port;
			this.setName("SSL_Server");
		}else{
			httpPort=port;
			this.setName("HTTP_Server");
		}
		serverType=type;

	}


	public static void init(Properties serverConfig) throws IOException {

		_serverConfig = serverConfig;

		File mtFile = new File(_serverConfig.getProperty("server.root")
				+ "mime.types");

		try {
			BufferedReader br = new BufferedReader(new FileReader(mtFile));
			String line = "";

			while ((line = br.readLine()) != null) {

				StringTokenizer MTtype = new StringTokenizer(line, "=");
				_mt.put(MTtype.nextToken(), MTtype.nextToken());
			}
		} catch (IOException e) {
		}

		//Loads SOAP applications

		File soapDir =new File(_serverConfig.getProperty("server.root")+
				_serverConfig.getProperty("soap-services.root"));


		if (!soapDir.isDirectory()){
			System.err.println("Soap-services directory not found. Can't load Services");
		}else{
			String[] files = soapDir.list();
			for (int i=0;i<files.length;i++){

				if (files[i].lastIndexOf(".jar")!=-1){
					ClassLoaderUtil.addFile(soapDir.getAbsolutePath()+"\\"+files[i]);				
					String appName=files[i].substring(0,files[i].lastIndexOf('.'));
					try {
						Class c=Class.forName(_serverConfig.getProperty(appName+".startup"));
						String constructorParams=(_serverConfig.getProperty(appName+".startup.params"));
						
						if (constructorParams==null)
							soapApplications.put("/"+appName, c.newInstance());
						else{
							StringTokenizer t = new StringTokenizer(constructorParams,";");
							ArrayList al=new ArrayList();
							while (t.hasMoreTokens()){
								String p =(String) t.nextElement();
								al.add(p);
							}
							
							String[] spar=new String[al.size()];
							for (int ind=0;ind<al.size();ind++){
								spar[ind]=(String)al.get(ind);
							}
							
							Constructor cons= c.getConstructor(new Class[]{String[].class});
							cons.setAccessible(true);
							if (cons != null){
								soapApplications.put("/"+appName, cons.newInstance(new Object[]{spar}));								
							}
						}
						
					} catch (Exception e) {
						soapApplications.put("/"+appName, new SOAPApplication());
						System.err.println("StartUp class for "+appName
								+" application can't be loaded or not defined["+_serverConfig.getProperty(appName+".startup")
								+", default startup class created");
					}
					System.out.println("soap Application:" +"/"+appName+" loaded");
				}
			}
		}



	}


	public void run() {
		//only one thread will be listening at SSLsocket
		if (!sslInitiated){
			//it must be an SSL server
			System.out.println("SSL server Started\n----------------------");
			sslInitiated=true;
			main2();
			System.exit (0);
		}
		//only one thread will be listening at Socket
		if (!httpInitiated){
			//it must be an SSL server
			System.out.println("HTTP server Started\n----------------------");
			httpInitiated=true;
			main1();
			System.exit (0);
		}
		
		try {
		//Each thread created by the listeners Threads execute this...
		if (serverType==SSL_PORT_TYPE){		
		System.out.println("SSL Session Started\n----------------------");

		 // Begin reading request
			dataFromClient = ssl_s.getInputStream();
			dataToClient = ssl_s.getOutputStream();
			httpRequest= new HttpRequest(dataFromClient);
			httpResponse = new HttpResponse (dataToClient);
			httpRequest.setInetAddress(ssl_s.getInetAddress());
			parseRequest(); // handle request
			sendResponse(); // if all else fails send a 500 error

			//dataToClient.flush();
			//dataToClient.close();
			//dataFromClient.close();
		
		}else{

		System.out.println("Session Started\n----------------------");
	// Begin reading request
			dataFromClient = _s.getInputStream();
			dataToClient = _s.getOutputStream();
			httpRequest= new HttpRequest(dataFromClient);
			httpResponse = new HttpResponse (dataToClient);
			httpRequest.setInetAddress(_s.getInetAddress());
			parseRequest(); // handle request
			sendResponse(); // if all else fails send a 500 error
			//
		}
	
			dataToClient.flush();
			dataToClient.close();
			dataFromClient.close();
			if (_s!=null) _s.close();
			if (ssl_s!=null) ssl_s.close();
		
		} catch (Exception e) {
			System.out.println(e.getLocalizedMessage());
		}
		
		
	}



	private String readLine(InputStream is) {
		char a='\n';
		StringBuffer sb =new StringBuffer();
		//if (is.available()>0){ 
		//we can't check availability because SSLsocket always returns 0
		int i=0;
		try{
			a = (char) is.read();

			while ((a=='\n')&& i<MAX_HEADER_SIZE) { a=(char) is.read(); i++;}
			while ((a != '\n')&& i<MAX_HEADER_SIZE){
				if (a!='\r') sb.append(a);
				a = (char) is.read();
				i++;
			}
		} catch(Exception e){}

		return sb.toString();
	}
	
	public void parseRequest() throws FileNotFoundException, IOException,
	InterruptedException {
		// method which parses the incoming request line by line

		String thisline = readLine(dataFromClient);
		if (_debug) System.out.println(thisline);
		StringTokenizer line = new StringTokenizer(thisline, "\r");
		HashMap HTTPvars = new HashMap();
		Vector tempV = new Vector();
		String rqline = "";

		if (_debug)System.out.println("Parsing Request");

		while (!thisline.equals("")) {
			if (thisline.indexOf(':')!=-1){
				httpRequest.setParameter(
					thisline.substring(0, thisline.indexOf(':')),
					thisline.substring(thisline.indexOf(':')+1,thisline.length()));
				
			}
			tempV.addElement(thisline);
			thisline = readLine(dataFromClient);
		}
		if (tempV.size()==0) return; //VOID header
		parseHeaders(tempV); // Parse extra headers like referrer


		// begin parsing the request line
		rqline = (String) tempV.elementAt(0);
		String[] request = new String[3];

		// will get the method type, file location, and http Ver		
		int count = 3;
		request[0]=rqline.substring(0,rqline.indexOf(' '));
		request[1]=rqline.substring(rqline.indexOf(' ')+1,rqline.indexOf("HTTP")-1);
		request[2]=rqline.substring(rqline.indexOf("HTTP"));
		if (request[2]==null) count = 2;
		else count = 3;




		if (count == 2) { // No protocol 0.9 is assumed
			httpVer = "0.9";
			methodType = request[0];
			checkMethod(methodType);
			url = request[1];
			checkUrl(url);
		}

		else if (count == 3) { // Valid request so far
			httpVerSt = request[2];
			checkHttpVer(request);
			methodType = request[0];
			checkMethod(methodType);
			url = request[1];
			checkUrl(url);
		}

		else { // Bad request
			httpVer = "1.0";
			sendError(400, "Bad Request -- more than 3 args");

		}

	}

	public void checkMethod(String meth) throws IOException {

		// Method which validates the users method

		meth = meth.toUpperCase();
		methodType = meth;
		if (((meth.equals("GET")) || (meth.equals("POST")) || (meth
				.equals("HEAD")))) {
			validMethod = true;
		} else if (((meth.equals("OPTIONS")) || (meth.equals("PUT"))
				|| (meth.equals("DELETE")) || (meth.equals("TRACE")))) {
			validMethod = false;
			sendError(501, "Method Not Implemented");
		} else {
			validMethod = false;
			sendError(400, "Bad Request -- Uknown Method");
			httpVer = "1.0";
		}
	}

	public void checkUrl(String newUrl) throws FileNotFoundException,
	IOException, InterruptedException {

		// method which parses and checks the URL portion of the request line

		if (_debug)System.out.println("Checking url");

		String resource = url.substring(url.lastIndexOf('/'));
		if (soapApplications.containsKey(resource)){
			Plugin soapApplication= (Plugin) soapApplications.get(resource);
			try {
				sendSoapResponse(soapApplication.doPost(httpRequest,httpResponse));
			} catch (HttpException e) {
				e.printStackTrace();
			}

		} else
			if (url.equals("/")) {
				
				if (_debug)System.out.println("There's nothing but a /");
				filename = _serverConfig.getProperty("default.doc");
				serverRoot = _serverConfig.getProperty("server.root");
				filepath = serverRoot + _serverConfig.getProperty("doc.root");
				filetype = _serverConfig.getProperty("default.type");
				File defFile = new File(filepath, filename);

				// check if it is a SOAP action and execute it
				getCT(filename);
				sendFile(defFile);

			}else
				if ((methodType.equals("GET")) || (methodType.equals("POST"))
						|| (methodType.equals("HEAD"))) {
					{

						if (url.startsWith("/")) {
							StringTokenizer rqline = new StringTokenizer(url, "/");

							while (rqline.hasMoreTokens() && cnt)

								// llop through the URL

							{
								ques = rqline.nextToken();
								quesE = ques.indexOf("?");
								// if ((quesE != -1) ||
								// (url.regionMatches(true,0,"cgi",0,url.length())))
								if ((quesE != -1) || (ques.indexOf(".cgi") != -1)) {
									// We've got a cgi to proccess
									// or we've got a wsdl request
									if (_debug)System.out.println("There's a ? mark or a cgi");
									if (quesE != -1) {
										StringTokenizer splitQ = new StringTokenizer(
												ques, "?");
										filenm = splitQ.nextToken();
										if (splitQ.hasMoreElements())
											cgivars = splitQ.nextToken();
										handleCGI(filenm, cgivars);
									} else {
										// We've got a cgi with out a ? mark

										if (_debug)System.out.println("gotcha");
										filenm = ques;
										handleCGI(filenm, "");
									}
								} else if ((quesE == -1)) {

									// incoming URL request has no cgi in it or ? -- its
									// a static file
									if (_debug)System.out.println("There's no ? mark -- not cgi");
									if (_debug)System.out.println("Anything but POST file: ");
									temp = temp + ques;

									filepath = _serverConfig.getProperty("server.root")
									+ _serverConfig.getProperty("doc.root");
									File staticFile = new File(URLDecoder.decode(filepath),URLDecoder.decode( temp));
									if (staticFile.isDirectory()) {
										// loop through the directories of the request

										temp = temp + "/";
										if (!rqline.hasMoreTokens()) {
											
											
											
											File defStaticFile = new File(URLDecoder.decode(_serverConfig
													.getProperty("server.root")
													+ _serverConfig
													.getProperty("doc.root")
													+ "/" + temp),
													URLDecoder.decode(_serverConfig
													.getProperty("default.doc")));
											
											getCT(_serverConfig
													.getProperty("default.doc"));
											sendFile(defStaticFile);
										}
									} else if ((staticFile.isFile())
											&& staticFile.canRead()) {

										// Its a valid file to read
										// System.out.println("staticfile = "
										// +staticFile+ "\n");
										filenm = ques;
										// temp = temp + filenm;
										cnt = false;
										// System.out.println("filenm = " + filenm +
										// "\n" );
										getCT(filenm);
										sendFile(staticFile);
									} else if (!staticFile.isFile()) {
										sendError(404, "File Not Found");
									} else if (!staticFile.canRead()) {
										sendError(403, "Forbidden -- File not readable");
									}

									else {

										if (_debug)System.out.println("Not found: " + filepath);
										sendError(404, "File not found");
									}
								}
							}
						}

					}
				}
	}

	public void checkHttpVer(String[] rq) throws IOException {

		// Method which tests the HTTP Protocol portion of the request line

		rq[2] = rq[2].toUpperCase();
		if (rq[2] == null) {
			httpVer = "0.9";
		} else if (rq[2].compareTo("HTTP/1.0") == 0) {
			httpVer = "1.0";
		} else if ((rq[2].startsWith("HTTP/")
				&& (!(rq[2].compareTo("HTTP/1.0") == 0)) && (!(rq[2]
				                                                  .compareTo("HTTP/0.9") == 0)))) {
			httpVer = "1.0";

		} else {
			httpVer = "1.0";
			sendError(400, "Bad HTTP Specification");
		}

	}

	public void parseHeaders(Vector v) {

		// Method which handles and parses the additional headers in the request
		// and stores them in Env Variables

		if (_debug)System.out.println("Parsing Headers");
		try {
			if (v.isEmpty()) {
				sendError(400, "Bad Request -- nothing");
			}
		} catch (IOException e) {
			System.err.println("IOException");
			System.exit(-1);
		}

		int vsize = v.size();
		int c;
		int b;
		String name = "";
		String value = "";
		String temp = "";
		StringTokenizer tp;

		if (vsize <= 1) {
			numEnvVars = 2;
			return;
		} else {

			// Test headers for validity

			numEnvVars = 2;
			for (int j = 1; j < vsize; j++) {
				temp = (String) v.elementAt(j);
				c = temp.indexOf(":");
				tp = new StringTokenizer(temp, ":");
				b = tp.countTokens();
				if (temp.indexOf("=") != -1) {
					body = true;
					if (_debug)System.out.println("Body = true");
				}
				if ((c == -1) && (body == false)) {
					if (_debug)System.out.println("Bad Header: " + temp);
					if (_debug)System.out.println("Removing Bad EnvVar: "
							+ (String) v.elementAt(j));
					v.removeElementAt(j);
					--j;
					--vsize;
				} else if ((b < 2) && (body == false)) {
					if (_debug)System.out.println("Bad Header: " + temp);
					if (_debug)System.out.println("Removing Bad EnvVar: "
							+ (String) v.elementAt(j));
					v.removeElementAt(j);
					--j;
					--vsize;
				}

				else {
					numEnvVars++;
				}
			}

			// begin filling the env variable array with valid headers

			headerArray = new String[numEnvVars - 2];
			if (_debug) System.out.println("numVectorelements: " + v.size());
			int d = 1;




			int endLoop =0;
			if (body == false)  endLoop = numEnvVars-2;
			else	endLoop = numEnvVars-3;

			for (int j = 0; j < endLoop; j++) {
				value = "";
				temp = (String) v.elementAt(d);
				StringTokenizer pos = new StringTokenizer(temp, ":");
				if ((pos.hasMoreTokens())) {
					name = pos.nextToken().trim();

					if (pos.hasMoreTokens()) {
						value = pos.nextToken().trim();
						while (pos.hasMoreTokens()) {
							value = value + ":" + pos.nextToken().trim();
						}
						if (name.contains("Content-Type") && value.contains("xml")) {
							this.isAnApplication=true;
							httpRequest.setParameter(name, value);
						}

						name = "HTTP_" + name.toUpperCase();
						if (_debug) System.out
						.println(" name = " + name.toUpperCase());
						if (_debug) System.out.println(" value = " + value);
						headerArray[j] = name + "=" + value;
						d++;
					}
				}
			} 
			if (body) headerArray[endLoop] = (String) v.lastElement();
		}
	}

	public void handleCGI(String fname, String cgiVars) throws IOException {

		// method which handles incoming cgi requests

		// System.out.println("Filename: "+ fname + "\r\nCGIVars: " + cgiVars);
		filepath = _serverConfig.getProperty("server.root")
		+ _serverConfig.getProperty("cgi.root");

		if (_debug) System.out.println("Filepath: " + filepath);
		File f = new File(filepath, fname);
		filepath = filepath + fname;
		if ((f.isFile()) && (f.canRead())) {
			// begin filling the enviroment variables
			env = new String[numEnvVars];
			env[0] = "REQUEST_METHOD=" + methodType;
			env[1] = "QUERY_STRING=" + cgiVars;
			if (_debug) System.out.println("env[0]: " + env[0]);
			if (_debug) System.out.println("env[1]: " + env[1]);
			int b = 0;
			for (int a = 2; a < numEnvVars; a++) {
				env[a] = headerArray[b];
				if (_debug) System.out.println("env[" + a + "]: " + env[a]);
				b++;
			}
			if (methodType.equals("GET")) {
				startCGI(filepath, env, "");
			} else if (methodType.equals("POST") && body == true) {
				// if post request must get the body of the request and store it
				// after validating the request

				int cl = 0;
				String x = "";
				String cleng = "HTTP_CONTENT-LENGTH";
				String ct = "HTTP_CONTENT-TYPE=APPLICATION/X-WWW-FORM-URLENCODED";
				String rqcleng = env[numEnvVars - 2];
				String rqct = env[numEnvVars - 3];

				if (!rqcleng.startsWith(cleng)) {
					if (_debug) System.out.println("incoming content length: " + rqcleng);
					if (_debug) System.out.println("should b content length: " + cleng);
					if (_debug) System.out.println("content length failed");
					sendError(400, "Bad POST Request -- Invalid Syntax");

				}
				if (!rqct.regionMatches(true, 0, ct, 0, rqct.length())) {
					if (_debug) System.out.println("content type failed");
					sendError(400, "Bad POST Request -- Invalid Syntax");
				}

				else {
					// Make sure content length is correct
					if (_debug) System.out.println("Its a Valid Post Request!!!!!!");
					StringTokenizer st = new StringTokenizer(rqcleng, "=");
					if ((st.hasMoreTokens()) && (st.countTokens() == 2)) {
						x = st.nextToken().trim();
						x = st.nextToken().trim();
						cl = new Integer(x).intValue();

					}
					if (_debug) System.out.println("content length supposed to be: " + cl);
					if (_debug) System.out.println("content length is------------: "
							+ (env[env.length - 1].length()));

					if (cl != ((env[env.length - 1].length()))) {
						sendError(400, "Content length not correct");
					}

					if (_debug) System.out.println("filepath: " + filepath);

				}

				startCGI(filepath, env, env[env.length - 1]);
			}
		} else if (!f.isFile()) {
			sendError(404, "File not found");
		} else if (!f.canRead()) {
			sendError(403, "Forbidden -- File not readable");
		} else {
			sendError(500, "Internal Server Error");
		}

	}

	public void startCGI(String fileName, String[] envs, String postBody) {

		// method which uns the cgi programs

		if (_debug) System.out.println("into startCGI");
		Process p = null;
		InputStream out;
		InputStreamReader isr;
		BufferedReader br;
		String s = "";
		Vector cgiOut = new Vector();

		String[] envVars;
		byte[] ba = postBody.getBytes();
		int m = 1;
		if (body == true) {
			String[] ta = new String[envs.length - 1];
			for (int w = 0; w < envs.length - 1; w++) {
				ta[w] = envs[w];
			}
			envVars = new String[ta.length];
			envVars = ta;
		} else {
			envVars = new String[envs.length];
			envVars = envs;
		}

		try {
			if (_debug) System.out.println("running cgi: " + fileName);
			p = Runtime.getRuntime().exec(fileName, envVars);
			try {
				OutputStream os = p.getOutputStream();
				os.write(ba);
				os.close();
				p.waitFor();
				m = p.exitValue();
			} catch (InterruptedException e) {
			}
		} catch (IOException i) {
		}
		// System.out.println("made it out of proccess");

		if (m == 0) {

			// cgi exited properly

			out =  p.getInputStream();
			isr = new InputStreamReader(out);
			br = new BufferedReader(isr);

			try {

				while ((s = br.readLine()) != null) {

					if (_debug) System.out.println(s);
					s = s + "\n";
					cgiOut.add(s);
				}
				br.close();
				isr.close();
				out.close();
				sent = true;

			} catch (IOException i) {
				System.out.println("IOexception");
			}
			// System.out.println("calling sendcgi");
			sendCGI(cgiOut);
		} else {

			// cgi did not exit properly
			try {
				sendError(500, "internal Server Error While Running cgi");
			} catch (IOException i) {
				if (_debug) System.out.println("IOexception");
			}
		}
	}

	public void sendCGI(Vector c) {

		// method which sends the results fromthe cgi program

		String[] tmp = new String[c.size()];
		String s = "";
		byte[] tempb = new byte[1];
		if (_debug) System.out.println("into SendingCGI");

		try {
			for (int i = 0; i < c.size(); i++) {
				s = (String) c.elementAt(i);

				tempb = s.getBytes();
				dataToClient.write(tempb);
			}

		} catch (IOException e) {
		}

	}

	public void sendFile(File rqFile) throws FileNotFoundException,
	IOException, InterruptedException {
		//This method has been checked and corrected
		// method which sends static (non cgi) files
		String headers ="";
		if (_debug) System.out.println("Sending File: " + rqFile + "\n");
		DataInputStream br = new DataInputStream(new FileInputStream(rqFile));
		
		byte[] tempb;
		Date currentTime = new Date();
		headers = "HTTP/" + httpVer + " 200 OK\r\nDate: "
		+ getDate().format(currentTime);
		headers = headers + "\r\nContent-Type: " + ctype;
		headers = headers + "\r\nContent-Length: " + rqFile.length()+ "\r\n"+ "\r\n";
		
		tempb = headers.getBytes();
		dataToClient.write(tempb);
		
		byte[] chb = new byte[1024];
		int len=0;
		if (!methodType.equals("HEAD")) {
			while ( (len=br.read(chb))>-1){			
				dataToClient.write(chb, 0, len);
			}
		}
	
		sent = true;
	}

	public void sendResponse() throws IOException {
		// method which sends if nothing else worked

		if (!sent) {
			byte[] temp;
			String st;
			String err = "<HTML><HEAD><TITLE>Error 500</TITLE></HEAD> ";
			err = err
			+ "<BODY> <H1>Error: 500 Internal Server Error</H1></BODY></HTML>";

			st = "HTTP/1.0 500 Internal Server Error\r\n";
			st = st + "Connection: Close \r\n";
			st = st + "Content-length: " + err.length() + "\r\n";
			st = st + "Content-type: text/html \r\n\r\n";
			st = st + err;
			temp = st.getBytes();
			dataToClient.write(temp);
			st = "";
			
		}
		sent = true;
	}



	public void sendSoapResponse(String sb) throws IOException {
		// method which sends the soap service response 
		// method which sends an SOAP message

		if (_debug) System.out.println("Sending SOAP response\n");
		// FileReader fr = new FileReader(rqFile);
		String tempLine;
		byte[] tempb;

		Date currentTime = new Date();

		headers = "HTTP/" + httpVer + " 200 OK\n" +
				  "Date: "+ getDate().format(currentTime)+
				  "\nConnection: Close";
		
		if (sb.length()>0){
			headers +=  "\nContent-Length: " + sb.length();
			headers += "\nContent-Type: text/xml\r\n";
			headers += "\r\n" + sb;
		}
		tempb = headers.getBytes();
		dataToClient.write(tempb);
		sent = true;
	}

	public void sendError(int errNum, String errDes) throws IOException {

		// method which sends detailed error message
		if (_debug) System.out.println("Into SendError");

		if (!sent) {
			byte[] temp;
			String st;
			String err = "<HTML><HEAD><TITLE>Error " + errNum + ": " + errDes
			+ "</TITLE></HEAD> ";
			err = err + "<BODY> <H1>Error: " + errNum + " " + errDes
			+ "</H1></BODY></HTML>";

			st = "HTTP/" + httpVer + " " + errNum + " " + errDes + "\r\n";
			st = st + "Connection: Close \r\n";
			st = st + "Content-length: " + err.length() + "\r\n";
			st = st + "Content-type: text/html \r\n \r\n";
			st = st + err;
			temp = st.getBytes();
			dataToClient.write(temp);
			st = "";

		}
		sent = true;
	}

	public void getCT(String rqFile) {

		// method which gets the content type of files

		if (_debug) System.out.print("Into Content Type \n");
		StringTokenizer st = new StringTokenizer(rqFile, ".");

		String fname = st.nextToken();
		if (_debug) System.out.print("Fname: " + fname + " \n");

		String ext = st.nextToken();
		if (_debug) System.out.print("Ext: " + ext + " \n");
		ctype = (String) _mt.get(ext);

	}

	public SimpleDateFormat getDate() {

		// method which gets the time

		String dateFormatString = "EEE, dd MMM yyyy, kk:mm:ss z";
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormatString);
		sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
		return sdf;
	}


	public static void main2(){
		try {
			//TODO enable client authentication
			SSLServerSocketFactory sslserversocketfactory =
				(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
			SSLServerSocket sslserversocket =
				(SSLServerSocket) sslserversocketfactory.createServerSocket(sslPort);
			
			
			while (true) { // loop forever
				SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); // Blocks waiting for a new connection
				SSHttpServerSSL serv = new SSHttpServerSSL(sslPort,SSL_PORT_TYPE);  // Create a new child process
				serv.ssl_s=sslsocket;
				serv.start(); // Start the child process
			}
		}  catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	public static void main1()  {


		ServerSocket ss;
		try {
			ss = new ServerSocket(httpPort);

			//main thread will attend Http connections
			while (true) { // loop forever
				Socket s = ss.accept(); // Blocks waiting for a new connection
				SSHttpServerSSL serv = new SSHttpServerSSL(httpPort,HTTP_PORT_TYPE);  // Create a new child process
				serv._s = s;
				serv.start(); // Start the child process
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	public static void main(String[] args) throws FileNotFoundException,
	IOException, InterruptedException, NoSuchMethodError {
		Properties serverConfig = new Properties();

		serverConfig.load(new FileInputStream(new File(".").getCanonicalPath()
				+ "/srm.conf"));



		int httpport = new Integer(serverConfig.getProperty("httpport")).intValue();
		int sslport = new Integer(serverConfig.getProperty("sslport")).intValue();
		
		init(serverConfig);

		//new Thread will attend SSL connections
		SSHttpServerSSL sslServ = new SSHttpServerSSL(sslport,SSL_PORT_TYPE);
		sslServ.start();
		//new thread will attend Http connections
		SSHttpServerSSL httpServ = new SSHttpServerSSL(httpport,HTTP_PORT_TYPE);  // Create a new child process
		httpServ.start(); // Start the child process
		
	}
}
